package com.wangdong.wdutils.utils;

import android.annotation.TargetApi;
import android.app.Activity;
import android.app.KeyguardManager;
import android.content.Context;
import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.graphics.Rect;
import android.os.Build;
import android.util.DisplayMetrics;
import android.util.TypedValue;
import android.view.Surface;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;

import java.lang.reflect.Field;
import java.lang.reflect.Method;

/**
 * @author luyz
 * 获得屏幕相关的辅助类
 *  代码里面的加0.5f，其目的是四舍五入，因为浮点数强制转为整型时，
 *   小数点后面数值会被直接咔嚓掉，所以如果原小数位后大于0.5，再加0.5就会进一，就曲线实现了四舍五入。
 */
public class DLScreenUtil {
	private DLScreenUtil() {
		/* cannot be instantiated */
		throw new UnsupportedOperationException("cannot be instantiated");
	}

	/**
	 * 根据手机的分辨率从 dp 的单位 转成为 px(像素)  。
	 */
	public static int dip2px(Context context, float dpValue) {
		final float scale = context.getResources().getDisplayMetrics().density;
		return (int) (dpValue * scale + 0.5f);
	}


	/**
	 * 根据手机的分辨率从 px(像素) 的单位 转成为 dp 。
	 */
	public static int px2dip(Context context, float pxValue) {
		final float scale = context.getResources().getDisplayMetrics().density;
		return (int) (pxValue / scale + 0.5f);
	}



	/**
	 * 得到设备屏幕的宽度
	 */
	public static int getScreenWidths(Context context) {
		return context.getResources().getDisplayMetrics().widthPixels;
	}

	/**
	 * 得到设备屏幕的高度
	 */
	public static int getScreenHeights(Context context) {
		return context.getResources().getDisplayMetrics().heightPixels;
	}

	/**
	 * 得到设备的密度
	 */
	public static float getScreenDensity(Context context) {
		return context.getResources().getDisplayMetrics().density;
	}
	/**
	 * 获得屏幕高度
	 * 
	 * @param context Context
	 * @return int
	 */
	public static int getScreenWidth(Context context) {
		WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
		DisplayMetrics outMetrics = new DisplayMetrics();
		wm.getDefaultDisplay().getMetrics(outMetrics);
		return outMetrics.widthPixels;
	}

	/**
	 * 获得屏幕宽度
	 * 
	 * @param context Context
	 * @return int
	 */
	public static int getScreenHeight(Context context) {
		WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
		DisplayMetrics outMetrics = new DisplayMetrics();
		wm.getDefaultDisplay().getMetrics(outMetrics);
		return outMetrics.heightPixels;
	}

	/**
	 * 获得状态栏的高度
	 * 
	 * @param context Context
	 * @return int
	 */
	public static int getStatusHeight(Context context) {

		int statusHeight = -1;
		try {
			Class<?> clazz = Class.forName("com.android.internal.R$dimen");
			Object object = clazz.newInstance();
			int height = Integer.parseInt(clazz.getField("status_bar_height").get(object).toString());
			statusHeight = context.getResources().getDimensionPixelSize(height);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return statusHeight;
	}

	/**
	 * 获取当前屏幕截图，包含状态栏
	 * 
	 * @param activity Activity
	 * @return Bitmap
	 */
	public static Bitmap snapShotWithStatusBar(Activity activity) {
		View view = activity.getWindow().getDecorView();
		view.setDrawingCacheEnabled(true);
		view.buildDrawingCache();
		Bitmap bmp = view.getDrawingCache();
		int width = getScreenWidth(activity);
		int height = getScreenHeight(activity);
		Bitmap bp = null;
		bp = Bitmap.createBitmap(bmp, 0, 0, width, height);
		view.destroyDrawingCache();
		return bp;

	}
	
	/**
	 * 获取当前屏幕截图，包含状态栏
	 * 
	 * @param  activity FragmentActivity
	 * @return Bitmap
	 */
	public static Bitmap snapShotWithStatusBarFromFragment(Activity activity) {
		View view = activity.getWindow().getDecorView();
		view.setDrawingCacheEnabled(true);
		view.buildDrawingCache();
		Bitmap bmp = view.getDrawingCache();
		int width = getScreenWidth(activity);
		int height = getScreenHeight(activity);
		Bitmap bp = null;
		bp = Bitmap.createBitmap(bmp, 0, 0, width, height);
		view.destroyDrawingCache();
		return bp;

	}

	/**
	 * 获取当前屏幕截图，不包含状态栏
	 * 
	 * @param activity Activity
	 * @return Bitmap
	 */
	public static Bitmap snapShotWithoutStatusBar(Activity activity) {
		View view = activity.getWindow().getDecorView();
		view.setDrawingCacheEnabled(true);
		view.buildDrawingCache();
		Bitmap bmp = view.getDrawingCache();
		Rect frame = new Rect();
		activity.getWindow().getDecorView().getWindowVisibleDisplayFrame(frame);
		int statusBarHeight = frame.top;

		int width = getScreenWidth(activity);
		int height = getScreenHeight(activity);
		Bitmap bp = null;
		bp = Bitmap.createBitmap(bmp, 0, statusBarHeight, width, height - statusBarHeight);
		view.destroyDrawingCache();
		return bp;

	}
	
	/**
	 * 获取当前屏幕截图，不包含状态栏
	 * 
	 * @param  activity FragmentActivity
	 * @return Bitmap
	 */
	public static Bitmap snapShotWithoutStatusBarFromFragment(Activity activity) {
		View view = activity.getWindow().getDecorView();
		view.setDrawingCacheEnabled(true);
		view.buildDrawingCache();
		Bitmap bmp = view.getDrawingCache();
		Rect frame = new Rect();
		activity.getWindow().getDecorView().getWindowVisibleDisplayFrame(frame);
		int statusBarHeight = frame.top;

		int width = getScreenWidth(activity);
		int height = getScreenHeight(activity);
		Bitmap bp = null;
		bp = Bitmap.createBitmap(bmp, 0, statusBarHeight, width, height - statusBarHeight);
		view.destroyDrawingCache();
		return bp;

	}

	/**
	 * 获取当前View的高度
	 * 
	 * @param ctx  Context
	 * @param view customeView
	 * @return View的高度
	 */
	public static int getViewHeight(Context ctx, View view) {
		return view.getMeasuredHeight();
	}

	/**
	 * 获取当前View的宽度
	 * 
	 * @param ctx  Context
	 * @param view customeView
	 * @return View的宽度
	 */
	public static int getViewWidth(Context ctx, View view) {
		return view.getMeasuredWidth();
	}
	
	/**
	 * 判断当前是不是平板设备
	 * @param context Context
	 * @return boolean
	 */
	public static boolean isTablet(Context context) {
		return (context.getResources().getConfiguration().screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) >= Configuration.SCREENLAYOUT_SIZE_LARGE;
	}





	/**
	 * 设置屏幕为横屏
	 * <p>还有一种就是在Activity中加属性android:screenOrientation="landscape"</p>
	 * <p>不设置Activity的android:configChanges时，切屏会重新调用各个生命周期，切横屏时会执行一次，切竖屏时会执行两次</p>
	 * <p>设置Activity的android:configChanges="orientation"时，切屏还是会重新调用各个生命周期，切横、竖屏时只会执行一次</p>
	 * <p>设置Activity的android:configChanges="orientation|keyboardHidden|screenSize"（4.0以上必须带最后一个参数）时
	 * 切屏不会重新调用各个生命周期，只会执行onConfigurationChanged方法</p>
	 *
	 * @param activity activity
	 */
	public static void setLandscape(Activity activity) {
		activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
	}

	/**
	 * 设置屏幕为竖屏
	 *
	 * @param activity activity
	 */
	public static void setPortrait(Activity activity) {
		activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
	}

	/**
	 * 判断是否横屏
	 *
	 * @param context 上下文
	 * @return {@code true}: 是<br>{@code false}: 否
	 */
	public static boolean isLandscape(Context context) {
		return context.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE;
	}

	/**
	 * 判断是否竖屏
	 *
	 * @param context 上下文
	 * @return {@code true}: 是<br>{@code false}: 否
	 */
	public static boolean isPortrait(Context context) {
		return context.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT;
	}

	/**
	 * 获取屏幕旋转角度
	 *
	 * @param activity activity
	 * @return 屏幕旋转角度
	 */
	public static int getScreenRotation(Activity activity) {
		switch (activity.getWindowManager().getDefaultDisplay().getRotation()) {
			default:
			case Surface.ROTATION_0:
				return 0;
			case Surface.ROTATION_90:
				return 90;
			case Surface.ROTATION_180:
				return 180;
			case Surface.ROTATION_270:
				return 270;
		}
	}

	/**
	 * 获取当前屏幕截图，包含状态栏
	 *
	 * @param activity activity
	 * @return Bitmap
	 */
	public static Bitmap captureWithStatusBar(Activity activity) {
		View view = activity.getWindow().getDecorView();
		view.setDrawingCacheEnabled(true);
		view.buildDrawingCache();
		Bitmap bmp = view.getDrawingCache();
		int width = getScreenWidth(activity);
		int height = getScreenHeight(activity);
		Bitmap ret = Bitmap.createBitmap(bmp, 0, 0, width, height);
		view.destroyDrawingCache();
		return ret;
	}

	/**
	 * 获取当前屏幕截图，不包含状态栏
	 * <p>需要用到上面获取状态栏高度getStatusBarHeight的方法</p>
	 *
	 * @param activity activity
	 * @return Bitmap
	 */
	public static Bitmap captureWithoutStatusBar(Activity activity) {
		View view = activity.getWindow().getDecorView();
		view.setDrawingCacheEnabled(true);
		view.buildDrawingCache();
		Bitmap bmp = view.getDrawingCache();
		int statusBarHeight = getStatusBarHeight(activity);
		int width = getScreenWidth(activity);
		int height = getScreenHeight(activity);
		Bitmap ret = Bitmap.createBitmap(bmp, 0, statusBarHeight, width, height - statusBarHeight);
		view.destroyDrawingCache();
		return ret;
	}

	/**
	 * 获取DisplayMetrics对象
	 *
	 * @param context 应用程序上下文
	 * @return
	 */
	public static DisplayMetrics getDisplayMetrics(Context context) {
		WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
		DisplayMetrics displayMetrics = new DisplayMetrics();
		windowManager.getDefaultDisplay().getMetrics(displayMetrics);
		return displayMetrics;
	}

	/**
	 * 判断是否锁屏
	 *
	 * @param context 上下文
	 * @return {@code true}: 是<br>{@code false}: 否
	 */
	public static boolean isScreenLock(Context context) {
		KeyguardManager km = (KeyguardManager) context
				.getSystemService(Context.KEYGUARD_SERVICE);
		return km.inKeyguardRestrictedInputMode();
	}


	/**
	 * 设置安全窗口，禁用系统截屏。防止 App 中的一些界面被截屏，并显示在其他设备中造成信息泄漏。
	 * （常见手机设备系统截屏操作方式为：同时按下电源键和音量键。）
	 *
	 * @param activity
	 */
	public static void noScreenshots(Activity activity) {
		activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_SECURE);
	}
	/**
	 * 隐藏状态栏
	 * <p>也就是设置全屏，一定要在setContentView之前调用，否则报错</p>
	 * <p>此方法Activity可以继承AppCompatActivity</p>
	 * <p>启动的时候状态栏会显示一下再隐藏，比如QQ的欢迎界面</p>
	 * <p>在配置文件中Activity加属性android:theme="@android:style/Theme.NoTitleBar.Fullscreen"</p>
	 * <p>如加了以上配置Activity不能继承AppCompatActivity，会报错</p>
	 *
	 * @param activity activity
	 */
	public static void hideStatusBar(Activity activity) {
		noTitle(activity);
		FLAG_FULLSCREEN(activity);
	}

	/**
	 * 设置透明状态栏(api大于19方可使用)
	 * <p>可在Activity的onCreat()中调用</p>
	 * <p>需在顶部控件布局中加入以下属性让内容出现在状态栏之下</p>
	 * <p>android:clipToPadding="true"</p>
	 * <p>android:fitsSystemWindows="true"</p>
	 *
	 * @param activity activity
	 */
	public static void setTransparentStatusBar(Activity activity) {
		if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
			activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);  //透明状态栏
			activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION); //透明导航栏
		}
	}

	/**
	 * 隐藏Title
	 * 一定要在setContentView之前调用，否则报错
	 *
	 * @param activity
	 */
	public static void setNoTitle(Activity activity) {
		activity.requestWindowFeature(Window.FEATURE_NO_TITLE);
	}

	public static void noTitle(Activity activity) {
		setNoTitle(activity);
	}

	/**
	 * 全屏
	 * 也就是设置全屏，一定要在setContentView之前调用，否则报错
	 *
	 * @param activity
	 */
	public static void FLAG_FULLSCREEN(Activity activity) {
		activity.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
	}

	/**
	 * 获取状态栏高度
	 *
	 * @param context 上下文
	 * @return 状态栏高度
	 */
	public static int getStatusBarHeight(Context context) {
		int result = 0;
		int resourceId = context.getResources()
				.getIdentifier("status_bar_height", "dimen", "android");
		if (resourceId > 0) {
			result = context.getResources().getDimensionPixelSize(resourceId);
		}
		return result;
	}

	/**
	 * 判断状态栏是否存在
	 *
	 * @param activity activity
	 * @return {@code true}: 存在<br>{@code false}: 不存在
	 */
	public static boolean isStatusBarExists(Activity activity) {
		WindowManager.LayoutParams params = activity.getWindow().getAttributes();
		return (params.flags & WindowManager.LayoutParams.FLAG_FULLSCREEN) != WindowManager.LayoutParams.FLAG_FULLSCREEN;
	}

	/**
	 * 获取ActionBar高度
	 *
	 * @param activity activity
	 * @return ActionBar高度
	 */
	public static int getActionBarHeight(Activity activity) {
		TypedValue tv = new TypedValue();
		if (activity.getTheme().resolveAttribute(android.R.attr.actionBarSize, tv, true)) {
			return TypedValue.complexToDimensionPixelSize(tv.data, activity.getResources().getDisplayMetrics());
		}
		return 0;
	}

	/**
	 * 显示通知栏
	 * <p>需添加权限 {@code <uses-permission android:name="android.permission.EXPAND_STATUS_BAR"/>}</p>
	 *
	 * @param context        上下文
	 * @param isSettingPanel {@code true}: 打开设置<br>{@code false}: 打开通知
	 */
	public static void showNotificationBar(Context context, boolean isSettingPanel) {
		String methodName = (Build.VERSION.SDK_INT <= 16) ? "expand"
				: (isSettingPanel ? "expandSettingsPanel" : "expandNotificationsPanel");
		invokePanels(context, methodName);
	}

	/**
	 * 隐藏通知栏
	 * <p>需添加权限 {@code <uses-permission android:name="android.permission.EXPAND_STATUS_BAR"/>}</p>
	 *
	 * @param context 上下文
	 */
	public static void hideNotificationBar(Context context) {
		String methodName = (Build.VERSION.SDK_INT <= 16) ? "collapse" : "collapsePanels";
		invokePanels(context, methodName);
	}

	/**
	 * 反射唤醒通知栏
	 *
	 * @param context    上下文
	 * @param methodName 方法名
	 */
	private static void invokePanels(Context context, String methodName) {
		try {
			Object service = context.getSystemService("statusbar");
			Class<?> statusBarManager = Class.forName("android.app.StatusBarManager");
			Method expand = statusBarManager.getMethod(methodName);
			expand.invoke(service);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}


	//==============================================================================================以下设置状态栏相关
	/**
	 * 需要在布局中加入
	 android:clipToPadding="true"
	 android:fitsSystemWindows="true"
	 * 这两行属性
	 */


	/**
	 * 修改状态栏为全透明
	 *
	 * @param activity
	 */
	@TargetApi(19)
	public static void transparencyBar(Activity activity) {
		if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
			Window window = activity.getWindow();
			window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS
					| WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
			window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
					| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
					| View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
			window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
			window.setStatusBarColor(Color.TRANSPARENT);
			window.setNavigationBarColor(Color.TRANSPARENT);
		} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
			Window window = activity.getWindow();
			window.setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS,
					WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
		}
	}

	/**
	 * 修改状态栏颜色，支持4.4以上版本
	 *
	 * @param activity
	 * @param colorId
	 */
	public static void setStatusBarColor(Activity activity, int colorId) {

		if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
			Window window = activity.getWindow();
			//      window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
			window.setStatusBarColor(activity.getResources().getColor(colorId));
		} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
			//使用SystemBarTint库使4.4版本状态栏变色，需要先将状态栏设置为透明
			//可以百度也可以查看RxBarTool 相同方法就能找到处理方法
//            transparencyBar(activity);
//            SystemBarTintManager tintManager = new SystemBarTintManager(activity);
//            tintManager.setStatusBarTintEnabled(true);
//            tintManager.setStatusBarTintResource(colorId);
		}
	}

	/**
	 * 设置状态栏黑色字体图标，
	 * 适配4.4以上版本MIUIV、Flyme和6.0以上版本其他Android
	 *
	 * @param activity
	 * @return 1:MIUUI 2:Flyme 3:android6.0
	 */
	public static int StatusBarLightMode(Activity activity) {
		int result = 0;
		if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
			if (MIUISetStatusBarLightMode(activity.getWindow(), true)) {
				result = 1;
			} else if (FlymeSetStatusBarLightMode(activity.getWindow(), true)) {
				result = 2;
			} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
				activity.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
				result = 3;
			}
		}
		return result;
	}

	/**
	 * 已知系统类型时，设置状态栏黑色字体图标。
	 * 适配4.4以上版本MIUIV、Flyme和6.0以上版本其他Android
	 *
	 * @param activity
	 * @param type     1:MIUUI 2:Flyme 3:android6.0
	 */
	public static void StatusBarLightMode(Activity activity, int type) {
		if (type == 1) {
			MIUISetStatusBarLightMode(activity.getWindow(), true);
		} else if (type == 2) {
			FlymeSetStatusBarLightMode(activity.getWindow(), true);
		} else if (type == 3) {
			activity.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
		}

	}

	/**
	 * 清除MIUI或flyme或6.0以上版本状态栏黑色字体
	 */
	public static void StatusBarDarkMode(Activity activity, int type) {
		if (type == 1) {
			MIUISetStatusBarLightMode(activity.getWindow(), false);
		} else if (type == 2) {
			FlymeSetStatusBarLightMode(activity.getWindow(), false);
		} else if (type == 3) {
			activity.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE);
		}

	}


	/**
	 * 设置状态栏图标为深色和魅族特定的文字风格
	 * 可以用来判断是否为Flyme用户
	 *
	 * @param window 需要设置的窗口
	 * @param dark   是否把状态栏字体及图标颜色设置为深色
	 * @return boolean 成功执行返回true
	 */
	public static boolean FlymeSetStatusBarLightMode(Window window, boolean dark) {
		boolean result = false;
		if (window != null) {
			try {
				WindowManager.LayoutParams lp = window.getAttributes();
				Field darkFlag = WindowManager.LayoutParams.class
						.getDeclaredField("MEIZU_FLAG_DARK_STATUS_BAR_ICON");
				Field meizuFlags = WindowManager.LayoutParams.class
						.getDeclaredField("meizuFlags");
				darkFlag.setAccessible(true);
				meizuFlags.setAccessible(true);
				int bit = darkFlag.getInt(null);
				int value = meizuFlags.getInt(lp);
				if (dark) {
					value |= bit;
				} else {
					value &= ~bit;
				}
				meizuFlags.setInt(lp, value);
				window.setAttributes(lp);
				result = true;
			} catch (Exception e) {

			}
		}
		return result;
	}

	/**
	 * 设置状态栏字体图标为深色，需要MIUIV6以上
	 *
	 * @param window 需要设置的窗口
	 * @param dark   是否把状态栏字体及图标颜色设置为深色
	 * @return boolean 成功执行返回true
	 */
	public static boolean MIUISetStatusBarLightMode(Window window, boolean dark) {
		boolean result = false;
		if (window != null) {
			Class clazz = window.getClass();
			try {
				int darkModeFlag = 0;
				Class layoutParams = Class.forName("android.view.MiuiWindowManager$LayoutParams");
				Field field = layoutParams.getField("EXTRA_FLAG_STATUS_BAR_DARK_MODE");
				darkModeFlag = field.getInt(layoutParams);
				Method extraFlagField = clazz.getMethod("setExtraFlags", int.class, int.class);
				if (dark) {
					extraFlagField.invoke(window, darkModeFlag, darkModeFlag);//状态栏透明且黑色字体
				} else {
					extraFlagField.invoke(window, 0, darkModeFlag);//清除黑色字体
				}
				result = true;
			} catch (Exception e) {

			}
		}
		return result;
	}

}
